let CEventManager = cc.Class({
  extends: cc.Component,
  
  statics: {
    instance: null,
  },
  
  ctor: function () {
    this.m_EventData = {};
  },
  
  
  registerEvent: function (eventID, target, weight, callback, source) {
    let tempData = this.m_EventData[eventID] || [];
    
    for (let i = 0; i < tempData.length; i++) {
      let event = tempData[i];
      if (event.target === target) {
        return;
      }
    }
    
    tempData.push({
      target: target,
      callback: callback,
      weight: weight,
      source: source
    });
    tempData.sort(function (eventA, eventB) {
      let a = eventA.weight;
      let b = eventB.weight;
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else if (a === b) {
        return 0;
      }
    });
    this.m_EventData[eventID] = tempData;
  },
  
  releaseAllEvents(target) {
    this.releaseEvent(target, null);
  },
  
  releaseEvent: function (target, eventID) {
    if (!eventID) {
      //删除该对象上的所有注册事件
      for (let eventName in this.m_EventData) {
        let eventList = this.m_EventData[eventName];
        if (!eventList) {
          continue
        }
        for (let i = 0; i < eventList.length; i++) {
          let event = eventList[i];
          if (event.target === target) {
            eventList.splice(i, 1);
            break;
          }
        }
      }
    } else {
      let eventList = this.m_EventData[eventID];
      if (!eventList) {
        return;
      }
      for (let i = 0; i < eventList.length; i++) {
        let event = eventList[i];
        if (event.target === target) {
          eventList.splice(i, 1);
          break;
        }
      }
    }
  },
  
  dispatchEvent: function (eventID, eventData, source) {
    let tempData = this.m_EventData[eventID] || [];
    for (let i = tempData.length - 1; i >= 0; i--) {
      let event = tempData[i];
      let callback = event.callback;
      let target = event.target;
      //如果这个事件指定了事件源，且事件源不等于该源，则不触发
      if (event.source && event.source !== source) {
        continue;
      }
      if (target[callback]) {
        target[callback](eventData);
      } else {
        cc.error("无效的监听函数, 请检查", eventID, target, callback);
      }
    }
  },
});

cc.CEventManager = CEventManager;